﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Surface;
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;
using SurfaceCardsBoardLibrary.Interfaces;
using SurfaceCardsBoardLibrary;
using System.Windows.Media.Animation;

namespace SurfaceCardsGameKit
{
    /// <summary>
    /// Interaction logic for DeckUC.xaml
    /// </summary>
    public partial class DeckUC : SurfaceUserControl
    {
        private bool _isUsingEye;

        public Brush BackBackground
        {
            get { return (Brush)GetValue(BackBackgroundProperty); }
            set { SetValue(BackBackgroundProperty, value); }
        }
        public static readonly DependencyProperty BackBackgroundProperty =
            DependencyProperty.Register("BackBackground", typeof(Brush), typeof(DeckUC), new UIPropertyMetadata(null));

        Storyboard _activationSB;

        public DeckUC()
        {
            InitializeComponent();

            _activationSB = this.Resources["StoryboardActive"] as Storyboard;
        }

        private Deck Deck
        {
            get { return this.DataContext as Deck; }
        }

        private void Background_ContactDown(object sender, ContactEventArgs e)
        {
            e.Handled = true;
        }

        public Rect GetCardsDestinationRect()
        {
            var rect = new Rect(
                this.MainGrid.ColumnDefinitions.Take(4).Sum(cd => cd.ActualWidth),
                0,
                this.MainGrid.ColumnDefinitions[4].ActualWidth,
                this.MainGrid.ActualHeight);
            return rect;
        }

        #region Action

        private void ShowMosaic()
        {
            if (Deck == null)
                return;

            if (Deck.IsMosaicChecked)
            {
                foreach (var card in Deck)
                {
                    card.ScatterViewItem.Visibility = Visibility.Collapsed;
                }

                Mosaic.Visibility = Visibility.Visible;
            }
        }

        private void HideMosaic()
        {
            if (Deck == null)
                return;

            foreach (var card in Deck)
            {
                card.ScatterViewItem.Visibility = Visibility.Visible;
            }

            Mosaic.Visibility = Visibility.Collapsed;

            Mosaic.IsFront = false;
            ButtonBottom.IsChecked = false;
            ButtonTop.IsChecked = false;

            Dispatcher.BeginInvoke((Action)(() => Deck.UpdateDisposition(false, true)), System.Windows.Threading.DispatcherPriority.ContextIdle, null);
        }

        private void ChangeMozaicIsFront()
        {
            if (MosaicTop.IsChecked.Value)
            {
                Mosaic.IsFront = ButtonTop.IsChecked.Value || ButtonBottom.IsChecked.Value;
            }
        }

        #endregion

        #region Click

        private void ButtonBottom_Click(object sender, RoutedEventArgs e)
        {
            if (Deck.IsMosaicChecked)
            {
                ButtonTop.IsChecked = !ButtonTop.IsChecked;
                ChangeMozaicIsFront();
            }
            else ButtonBottom.IsChecked = !ButtonBottom.IsChecked;
        }

        private void ButtonTop_Click(object sender, RoutedEventArgs e)
        {
            if (Deck.IsMosaicChecked)
            {
                ButtonBottom.IsChecked = !ButtonBottom.IsChecked;
                ChangeMozaicIsFront();
            }
            else ButtonTop.IsChecked = !ButtonTop.IsChecked;
        }

        private void MosaicBottom_Click(object sender, RoutedEventArgs e)
        {
            if (MosaicBottom.IsChecked.Value)
            {
                MosaicTop.IsEnabled = false;
                ButtonTop.IsEnabled = false;

                if (Deck.DeckOrientation == DeckOrientation.Down)
                {
                    RotateTransform r = new RotateTransform(180);
                    Mosaic.RenderTransform = r;
                }
                else
                {
                    RotateTransform r = new RotateTransform(0);
                    Mosaic.RenderTransform = r;
                }

                ShowMosaic();
            }
            else
            {
                MosaicTop.IsEnabled = true;
                ButtonTop.IsEnabled = true;

                HideMosaic();
            }
        }

        private void MosaicTop_Click(object sender, RoutedEventArgs e)
        {
            if (MosaicTop.IsChecked.Value)
            {
                MosaicBottom.IsEnabled = false;
                ButtonBottom.IsEnabled = false;

                if (Deck.DeckOrientation == DeckOrientation.Down)
                {
                    RotateTransform r = new RotateTransform(180);
                    Mosaic.RenderTransform = r;
                }
                else
                {
                    RotateTransform r = new RotateTransform(0);
                    Mosaic.RenderTransform = r;
                }

                ShowMosaic();
            }
            else
            {
                MosaicBottom.IsEnabled = true;
                ButtonBottom.IsEnabled = true;

                HideMosaic();
            }
        }

        #endregion

        #region override

        protected override void OnContactChanged(ContactEventArgs e)
        {
            if (Deck == null || e.Contact.Captured != this)
                return;

            if (_isUsingEye)
            {
                foreach (var card in Deck)
                {
                    Card c = card as Card;
                    c.OpacityMaskPoint(e);
                }
            }
            else
            {
                Deck.ComputeCardsNeededToBeReturned(e.Contact);
            }

            e.Handled = true;
        }

        protected override void OnContactUp(ContactEventArgs e)
        {
            if (Deck == null || e.Contact.Captured != this)
                return;

            if (_isUsingEye)
            {
                foreach (var card in Deck)
                {
                    Card c = card as Card;
                    c.CancelOpacityMask();
                }
                _isUsingEye = false;
            }

            Deck.EndReturnCards();
        }

        private void Button_PreviewContactDown(object sender, ContactEventArgs e)
        {
            if (Deck.IsMosaicChecked == false)
            {
                e.Contact.Capture(this);
                e.Handled = true;
                _isUsingEye = true;
            }
        }

        protected override void OnPreviewContactDown(ContactEventArgs e)
        {
            base.OnPreviewContactDown(e);

            if (e.OriginalSource == BackRight || e.OriginalSource == BackLeft || e.OriginalSource == BackMiddle)
                Deck.CheckCaptureContactForCard(null, e);
        }

        #endregion

        #region Activation & Deactivation

        public bool IsActive
        {
            get { return (bool)GetValue(IsActiveProperty); }
            set { SetValue(IsActiveProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsActive.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsActiveProperty =
            DependencyProperty.Register("IsActive", typeof(bool), typeof(DeckUC), new UIPropertyMetadata(false, OnIsActiveChanged));


        private static void OnIsActiveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var isActive = (bool)e.NewValue;
            var deckUC = (DeckUC)d;

            if (isActive)
                deckUC._activationSB.Begin(deckUC.pathLeft, true);
            else
                deckUC._activationSB.Stop(deckUC.pathLeft);
        }

        #endregion

        private void ElementMenu_ContactDown(object sender, ContactEventArgs e)
        {
            // activate the SVI to set it foreground
            this.Deck.ScatterView.Activate(this.Deck);
        }

    }

}
